{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Title: #Valid Square"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Difficulty: #Medium"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Category Title: #Algorithms"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tag Slug: #geometry #math"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Name Translated: #几何 #数学"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solution Name: validSquare"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Title: #有效的正方形"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Content:\n",
    "<p>给定2D空间中四个点的坐标&nbsp;<code>p1</code>,&nbsp;<code>p2</code>,&nbsp;<code>p3</code>&nbsp;和&nbsp;<code>p4</code>，如果这四个点构成一个正方形，则返回 <code>true</code> 。</p>\n",
    "\n",
    "<p>点的坐标&nbsp;<code>p<sub>i</sub></code> 表示为 <code>[xi, yi]</code> 。 <code>输入没有任何顺序</code> 。</p>\n",
    "\n",
    "<p>一个 <strong>有效的正方形</strong> 有四条等边和四个等角(90度角)。</p>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>示例 1:</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入:</strong> p1 = [0,0], p2 = [1,1], p3 = [1,0], p4 = [0,1]\n",
    "<strong>输出:</strong> True\n",
    "</pre>\n",
    "\n",
    "<p><strong>示例 2:</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>p1 = [0,0], p2 = [1,1], p3 = [1,0], p4 = [0,12]\n",
    "<b>输出：</b>false\n",
    "</pre>\n",
    "\n",
    "<p><strong>示例 3:</strong></p>\n",
    "\n",
    "<pre>\n",
    "<b>输入：</b>p1 = [1,0], p2 = [-1,0], p3 = [0,1], p4 = [0,-1]\n",
    "<b>输出：</b>true\n",
    "</pre>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>提示:</strong></p>\n",
    "\n",
    "<ul>\n",
    "\t<li><code>p1.length == p2.length == p3.length == p4.length == 2</code></li>\n",
    "\t<li><code>-10<sup>4</sup>&nbsp;&lt;= x<sub>i</sub>, y<sub>i</sub>&nbsp;&lt;= 10<sup>4</sup></code></li>\n",
    "</ul>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Description: [valid-square](https://leetcode.cn/problems/valid-square/description/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solutions: [valid-square](https://leetcode.cn/problems/valid-square/solutions/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_cases = ['[0,0]\\n[1,1]\\n[1,0]\\n[0,1]', '[0,0]\\n[1,1]\\n[1,0]\\n[0,12]', '[1,0]\\n[-1,0]\\n[0,1]\\n[0,-1]']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        return items[0][1] == 4 and items[1][1] == 2 and items[1][0] == 2 * items[0][0] if (dist_cnts := Counter((b[0] - a[0]) ** 2 + (b[1] - a[1]) ** 2 for a, b in itertools.combinations([p1, p2, p3, p4], 2))) and len(items := sorted(dist_cnts.items())) == 2 else False\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        data = [p1,p2, p3, p4] \n",
    "        def cke(point, datas):\n",
    "            dis = collections.defaultdict(int)\n",
    "            for points in datas:\n",
    "                dist = self.com(point, points)\n",
    "                dis[dist]= dis.get(dist, 0)+1\n",
    "            if len(dis)!=2:return False\n",
    "            bians = 0\n",
    "            xiebian = 0\n",
    "            for key, val in dis.items():\n",
    "                if val == 2:\n",
    "                    bians = key\n",
    "                else:\n",
    "                    xiebian = key\n",
    "            if abs(sqrt(pow(bians,2)*2) - xiebian)<=0.000000000001:\n",
    "                return True\n",
    "            return False\n",
    "        for i in range(4):\n",
    "            cur = []\n",
    "            for j in range(4):\n",
    "                if i != j:\n",
    "                    cur.append(data[j])\n",
    "            if not cke(data[i], cur):\n",
    "                return False\n",
    "        return True\n",
    "\n",
    "    def com(self, point, p1):\n",
    "        return sqrt(pow(point[0]-p1[0],2)+pow(point[1]-p1[1],2)) \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "#利用正方形的判定条件：对角线相等且垂直平分\n",
    "        def check(a1,a2,a3,a4):\n",
    "            vec1=(a1[0]-a2[0],a1[1]-a2[1])\n",
    "            vec2=(a3[0]-a4[0],a3[1]-a4[1])\n",
    "            s1=vec1[0]**2+vec1[1]**2\n",
    "            s2=vec2[0]**2+vec2[1]**2\n",
    "            doc=vec1[0]*vec2[0]+vec1[1]*vec2[1]\n",
    "            m1=[(a1[0]+a2[0])/2,(a1[1]+a2[1])/2]\n",
    "            m2=[(a3[0]+a4[0])/2,(a3[1]+a4[1])/2]\n",
    "            if s1!=0 and s1==s2 and doc==0 and m1==m2:\n",
    "                return True\n",
    "            else:\n",
    "                return False\n",
    "\n",
    "        return check(p1,p2,p3,p4) or check(p1,p3,p2,p4) or check(p1,p4,p2,p3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        if p1[0] == p2[0] and p1[1] == p2[1]:\n",
    "            return False\n",
    "        def dis(st,ed):\n",
    "            return pow(ed[1]-st[1],2) + pow(ed[0]-st[0],2)\n",
    "        length = list()\n",
    "        length.append(dis(p1, p2))\n",
    "        length.append(dis(p1, p3))\n",
    "        length.append(dis(p1, p4))\n",
    "        length.append(dis(p2, p3))\n",
    "        length.append(dis(p2, p4))\n",
    "        length.append(dis(p3, p4))\n",
    "        length.sort()\n",
    "        if length[0] == length[3] and length[4] == length[5] and length[3] * 2 == length[4]:\n",
    "            return True\n",
    "        else:\n",
    "            return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        def dist(p1, p2):\n",
    "            x1, y1 = p1\n",
    "            x2, y2 = p2\n",
    "            return (x1 - x2)**2 + (y1 - y2)**2\n",
    "        d = [dist(p1, p2), dist(p1, p3), dist(p1, p4), dist(p2, p3), dist(p2, p4), dist(p3, p4)]\n",
    "        cnt = Counter(d)\n",
    "        dst = sorted(cnt)\n",
    "        return True if cnt[dst[0]] == 4 and cnt[dst[1]] == 2 and dst[0]*2 == dst[1] else False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "      stack = [[p1, p2], [p1, p3], [p1, p4], [p2, p3], [p2, p4], [p3, p4]]\n",
    "      line = collections.defaultdict(int)\n",
    "      for i in range(6):\n",
    "        x, y = stack[i]\n",
    "        line[(x[0] - y[0]) ** 2 + (x[1] - y[1]) ** 2] += 1\n",
    "      if len(line) != 2 or line[min(line.keys())] != 4:  return False\n",
    "      return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        def pick(p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "            if p1[0] + p3[0] == p2[0] + p4[0]:\n",
    "                if p1[1] + p3[1] == p2[1] + p4[1]:\n",
    "                    if (p1[0] - p3[0]) * (p2[0] - p4[0]) + (p1[1] - p3[1]) * (p2[1] - p4[1]) == 0:\n",
    "                        if abs(p1[0] - p3[0]) == abs(p2[1] - p4[1]):                     \n",
    "                           return True\n",
    "            return False\n",
    "        if p1 == p2:\n",
    "            return False\n",
    "        if pick(p1,p2,p3,p4) or pick(p1,p3,p4,p2) or pick(p1,p4,p2,p3):\n",
    "            return True\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        if p1[0] == p2[0] and p1[1] == p2[1]:\n",
    "            return False\n",
    "        def dis(st,ed):\n",
    "            return pow(ed[1]-st[1],2) + pow(ed[0]-st[0],2)\n",
    "        length = list()\n",
    "        length.append(dis(p1, p2))\n",
    "        length.append(dis(p1, p3))\n",
    "        length.append(dis(p1, p4))\n",
    "        length.append(dis(p2, p3))\n",
    "        length.append(dis(p2, p4))\n",
    "        length.append(dis(p3, p4))\n",
    "        length.sort()\n",
    "        if length[0] == length[3] and length[4] == length[5] and length[3] * 2 == length[4]:\n",
    "            return True\n",
    "        else:\n",
    "            return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        sq_len = None\n",
    "\n",
    "        def get_2_point_len(a: list, b: list) -> int:\n",
    "            return (a[1] - b[1]) ** 2 + (a[0] - b[0]) ** 2\n",
    "\n",
    "        def is_right_triangle(a: list, b: list, c: list) -> bool:\n",
    "            nonlocal sq_len\n",
    "            ab = get_2_point_len(a, b)\n",
    "            ac = get_2_point_len(a, c)\n",
    "            bc = get_2_point_len(b, c)\n",
    "            \n",
    "            ok = (ab == ac and ab + ac == bc) or (ab == bc and ab + bc == ac) or (ac == bc and ac + bc == ab)\n",
    " \n",
    "            if not ok: return False\n",
    "\n",
    "            if sq_len is None: \n",
    "                sq_len = min(ab, ac, bc)\n",
    "                if sq_len == 0: return False\n",
    "            else: \n",
    "                return sq_len == min(ab, ac, bc)\n",
    "\n",
    "            return True          \n",
    "\n",
    "        ans = is_right_triangle(p1, p2, p3) and is_right_triangle(p1, p2, p4) and is_right_triangle(p2, p3, p4)\n",
    "\n",
    "        return ans  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "#利用正方形的判定条件：对角线相等且垂直平分\n",
    "        # def check(a1,a2,a3,a4):\n",
    "        #     vec1=(a1[0]-a2[0],a1[1]-a2[1])\n",
    "        #     vec2=(a3[0]-a4[0],a3[1]-a4[1])\n",
    "        #     s1=vec1[0]**2+vec1[1]**2\n",
    "        #     s2=vec2[0]**2+vec2[1]**2\n",
    "        #     doc=vec1[0]*vec2[0]+vec1[1]*vec2[1]\n",
    "        #     m1=[(a1[0]+a2[0])/2,(a1[1]+a2[1])/2]\n",
    "        #     m2=[(a3[0]+a4[0])/2,(a3[1]+a4[1])/2]\n",
    "        #     if s1!=0 and s1==s2 and doc==0 and m1==m2:\n",
    "        #         return True\n",
    "        #     else:\n",
    "        #         return False\n",
    "\n",
    "        # return check(p1,p2,p3,p4) or check(p1,p3,p2,p4) or check(p1,p4,p2,p3)\n",
    "\n",
    "#利用set去重\n",
    "        def getdis(x1,x2,y1,y2):\n",
    "            return (x1-x2)**2+(y1-y2)**2\n",
    "        points=[p1,p2,p3,p4]\n",
    "        s=set()\n",
    "        for i in range(4):\n",
    "            for j in range(i+1,4):\n",
    "                l=getdis(points[i][0],points[j][0],points[i][1],points[j][1])\n",
    "                if l==0:return False\n",
    "                s.add(l)\n",
    "        return len(s)==2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        p = [p1, p2, p3, p4]\n",
    "        points = combinations(p, 2)\n",
    "        edges_sqr = [(p[0][0]-p[1][0])**2 + (p[0][1]-p[1][1])**2 for p in points]\n",
    "        edges_sqr = sorted(edges_sqr)\n",
    "        if edges_sqr[0] == edges_sqr[1] == edges_sqr[2] == edges_sqr[3] and edges_sqr[4] == edges_sqr[5] and 0 not in edges_sqr:\n",
    "            return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        def lt419(p1,p2,p3,p4):\n",
    "            def dist(p1,p2):\n",
    "                x1,y1=p1\n",
    "                x2,y2=p2\n",
    "                return (x2-x1)**2+(y2-y1)**2\n",
    "            dists=[dist(p1,p2),dist(p1,p3),dist(p1,p4),dist(p2,p3),dist(p2,p4),dist(p3,p4)]\n",
    "            dists.sort()\n",
    "            if dists[0]==0:return False\n",
    "            return dists[0]==dists[1]==dists[2]==dists[3] and dists[4]==dists[5] and dists[4]==dists[0]*2\n",
    "        return lt419(p1,p2,p3,p4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        if p1 == p2 == p3 == p4:\n",
    "            return False\n",
    "        \n",
    "        def eculid(p1,p2):\n",
    "            return ((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2) ** 0.5\n",
    "        \n",
    "        gh2 = 2 ** 0.5\n",
    "        dist1_2 = eculid(p1,p2)\n",
    "        dist1_3 = eculid(p1,p3)\n",
    "        dist1_4 = eculid(p1,p4)\n",
    "        dist2_3 = eculid(p2,p3)\n",
    "        dist2_4 = eculid(p2,p4)\n",
    "        dist3_4 = eculid(p3,p4)\n",
    "        dists = [dist1_2,dist1_3,dist1_4,dist2_3,dist2_4,dist3_4]\n",
    "        dists.sort()\n",
    "        if dists[0] == dists[1] == dists[2] == dists[3] and dists[4] == dists[5]:\n",
    "            return True\n",
    "        else:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\r\n",
    "        if p1 == p2 or p1 == p3 or p1 == p4 or p2 == p3 or p2 == p4 or p3 == p4:\r\n",
    "            return(False)\r\n",
    "\r\n",
    "        def judge(p1, p2, p3, p4):\r\n",
    "            # 平行四边形\r\n",
    "            if (p1[0] + p2[0] == p3[0] + p4[0]) and (p1[1] + p2[1] == p3[1] + p4[1]):\r\n",
    "                # 长方形\r\n",
    "                if (p2[0] - p1[0]) * (p4[0] - p3[0]) + (p2[1] - p1[1]) * (p4[1] - p3[1]) == 0:\r\n",
    "                    #  正方形\r\n",
    "                    if (p2[0] - p1[0]) ** 2 + (p2[1] - p1[1]) ** 2 == (p4[0] - p3[0]) ** 2 + (p4[1] - p3[1]) ** 2:\r\n",
    "                        return(True)\r\n",
    "            return(False)\r\n",
    "        flag = judge(p1, p2, p3, p4) | judge(p1, p3, p2, p4) | judge(p1, p4, p2, p3)\r\n",
    "        return(flag)\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        points = [p1, p2, p3, p4]\n",
    "        distances = []\n",
    "        for i in range(4):\n",
    "            for j in range(i+1, 4):\n",
    "                distances.append((points[i][0]-points[j][0])**2+(points[i][1]-points[j][1])**2)\n",
    "        distances.sort()\n",
    "        print(distances)\n",
    "        return distances[0] == distances[3] and distances[4] == distances[5] and distances[3]<distances[4]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        data = [p1,p2, p3, p4] \n",
    "        def cke(point, datas):\n",
    "            dis = collections.defaultdict(int)\n",
    "            for points in datas:\n",
    "                dist = self.com(point, points)\n",
    "                dis[dist]= dis.get(dist, 0)+1\n",
    "            if len(dis)!=2:return False\n",
    "            bians = 0\n",
    "            xiebian = 0\n",
    "            for key, val in dis.items():\n",
    "                if val == 2:\n",
    "                    bians = key\n",
    "                else:\n",
    "                    xiebian = key\n",
    "            if abs(sqrt(pow(bians,2)*2) - xiebian)<=0.000000000001:\n",
    "                return True\n",
    "            return False\n",
    "        for i in range(4):\n",
    "            cur = []\n",
    "            for j in range(4):\n",
    "                if i != j:\n",
    "                    cur.append(data[j])\n",
    "            if not cke(data[i], cur):\n",
    "                return False\n",
    "        return True\n",
    "\n",
    "    def com(self, point, p1):\n",
    "        return sqrt(pow(point[0]-p1[0],2)+pow(point[1]-p1[1],2)) \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        pts, ans = [p1, p2, p3, p4], []\n",
    "        for idx1 in range(len(pts)):\n",
    "            for idx2 in range(len(pts)):\n",
    "                if idx1 != idx2:\n",
    "                    cur = (pts[idx1][0] - pts[idx2][0])** 2 + (pts[idx1][1] - pts[idx2][1]) ** 2\n",
    "                    if cur not in ans:\n",
    "                        ans.append(cur)\n",
    "        return True if len(ans) == 2 and max(ans) == 2 * min(ans) else False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        # 正方形四个点两两计算边长 只会有两种长度: 边长/对角线\n",
    "        ans = set()\n",
    "        group = [(p1, p2), (p1, p3), (p1, p4), (p2, p3), (p2, p4), (p3, p4)]\n",
    "        for pair in group:\n",
    "            d1, d2 = pair\n",
    "            x1, y1 = d1\n",
    "            x2, y2 = d2\n",
    "            distance = (x2-x1) ** 2 + (y1-y2) ** 2\n",
    "            ans.add(distance)\n",
    "\n",
    "        return True if len(ans) == 2 and 0 not in ans else False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        l = [p1, p2, p3, p4]\n",
    "        res = set()\n",
    "        for i in range(0, 4):\n",
    "            for j in range(i+1, 4):\n",
    "                cur = (l[i][0] - l[j][0])**2 + (l[i][1] - l[j][1])**2\n",
    "                if cur == 0: return False\n",
    "                res.add(cur)\n",
    "        if len(res) != 2:   return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        def dist(a, b):\n",
    "            return (a[0] - b[0])**2 + (a[1] - b[1])**2\n",
    "        \n",
    "        arr = []\n",
    "        arr.append(dist(p1, p2))\n",
    "        arr.append(dist(p1, p3))\n",
    "        arr.append(dist(p1, p4))\n",
    "        arr.append(dist(p2, p3))\n",
    "        arr.append(dist(p2, p4))\n",
    "        arr.append(dist(p3, p4))\n",
    "        arr.sort()\n",
    "\n",
    "        if arr[0] == 0:\n",
    "            return False\n",
    "        \n",
    "        if arr[0] == arr[1] and arr[0] == arr[2] and arr[0] == arr[3] and arr[4] == arr[5] and 2 * arr[0] == arr[4] :\n",
    "            return True\n",
    "        \n",
    "        return False\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        def getdis(x1,x2,y1,y2):\n",
    "            return (x1-x2)**2+(y1-y2)**2\n",
    "        s=set()\n",
    "        points=[p1,p2,p3,p4]\n",
    "        for i in range(4):\n",
    "            for j in range(i+1,4):\n",
    "                l=getdis(points[i][0],points[j][0],points[i][1],points[j][1])\n",
    "                if l==0:return False\n",
    "                s.add(l)\n",
    "        return len(s)==2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        if p1[0] == p2[0] and p1[1] == p2[1]:\n",
    "            return False\n",
    "        def dis(st,ed):\n",
    "            return pow(ed[1]-st[1],2) + pow(ed[0]-st[0],2)\n",
    "        length = list()\n",
    "        length.append(dis(p1, p2))\n",
    "        length.append(dis(p1, p3))\n",
    "        length.append(dis(p1, p4))\n",
    "        length.append(dis(p2, p3))\n",
    "        length.append(dis(p2, p4))\n",
    "        length.append(dis(p3, p4))\n",
    "        length.sort()\n",
    "        if length[0] == length[3] and length[4] == length[5] and length[3] * 2 == length[4]:\n",
    "            return True\n",
    "        else:\n",
    "            return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        if p1==p2 or p1==p3 or p1==p4 or p2==p3 or p2==p4 or p3==p4:\n",
    "            return False\n",
    "        def dis(x,y):\n",
    "            return (x[0]-y[0])**2+(x[1]-y[1])**2\n",
    "        if dis(p1,p2)!=dis(p3,p4) or dis(p1,p3)!=dis(p2,p4) or dis(p1,p4)!=dis(p2,p3):\n",
    "            return False\n",
    "        if dis(p1,p2)==dis(p1,p3):\n",
    "            return True\n",
    "        if dis(p1,p2)==dis(p1,p4):\n",
    "            return True\n",
    "        if dis(p1,p3)==dis(p3,p2):\n",
    "            return True\n",
    " \n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def f(self, a, b, c, d):\n",
    "        l1 = [(i[0]-j[0])**2+(i[1]-j[1])**2 for i, j in pairwise([a, b, c, d, a])]\n",
    "        l2 = [(i[0]-j[0])**2+(i[1]-j[1])**2 for i, j in ((a, c), (d, b))]\n",
    "        return len(set(l1)) == len(set(l2)) == 1  and a!=b and a!=c\n",
    "\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        return any(self.f(*i) for i in itertools.permutations([p1, p2, p3, p4]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        def dis(p1: List[int], p2: List[int]):\n",
    "            x = (p1[0]-p2[0])**2+ (p1[1]-p2[1])**2\n",
    "            return x\n",
    "        res = []\n",
    "        res.append(dis(p1,p2))\n",
    "        res.append(dis(p2,p3))\n",
    "        res.append(dis(p3,p4))\n",
    "        res.append(dis(p1,p4))\n",
    "        res.append(dis(p2,p4))\n",
    "        res.append(dis(p1,p3))\n",
    "        res.sort()\n",
    "        num1 = res.count(res[0])\n",
    "        if num1 == 4:\n",
    "            num2 = res.count(res[4])\n",
    "            if num2 == 2:\n",
    "                return True\n",
    "        return False\n",
    "\n",
    "            \n",
    "            \n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        def calculateDistance(point1, point2):\n",
    "            return (point1[0] - point2[0]) ** 2 + (point1[1] - point2[1]) ** 2\n",
    "\n",
    "        if p1 == p2:\n",
    "            return False\n",
    "        point = [p1,p2,p3,p4]\n",
    "        distances = []\n",
    "        for i in range(4):\n",
    "            for j in range(i+1,4):\n",
    "                distances.append(calculateDistance(point[i], point[j]))\n",
    "        distances.sort()\n",
    "        if (\n",
    "            distances[0] == distances[1] == distances[2] == distances[3] and\n",
    "            distances[4] == distances[5] and\n",
    "            distances[4] == 2 * distances[0]\n",
    "        ):\n",
    "            return True\n",
    "        else:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        a,b=p1[0],p1[1]\n",
    "        c,d=p2[0],p2[1]\n",
    "        if a==b==c==d:\n",
    "            return False\n",
    "        else:\n",
    "            if p3==[c+b-d,d+c-a] and p4==[a+b-d,b+c-a]:\n",
    "                return True\n",
    "            elif p4==[c+b-d,d+c-a] and p3==[a+b-d,b+c-a]:\n",
    "                return True\n",
    "            elif p3==[(a+c+b-d)/2,(b+d+c-a)/2] and p4==[(a+c+d-b)/2,(b+d+a-c)/2]:\n",
    "                return True\n",
    "            elif p4==[(a+c+b-d)/2,(b+d+c-a)/2] and p3==[(a+c+d-b)/2,(b+d+a-c)/2]:\n",
    "                return True\n",
    "            elif p3==[c+d-b,d+a-c] and p4==[a+d-b,b+a-c]:\n",
    "                return True\n",
    "            elif p4==[c+d-b,d+a-c] and p3==[a+d-b,b+a-c]:\n",
    "                return True\n",
    "            else:\n",
    "                return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        l = [p1, p2, p3, p4]\n",
    "        res = set()\n",
    "        for i in range(0, 4):\n",
    "            for j in range(i+1, 4):\n",
    "                cur = (l[i][0] - l[j][0])**2 + (l[i][1] - l[j][1])**2\n",
    "                if cur == 0: return False\n",
    "                res.add(cur)\n",
    "        if len(res) != 2:   return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        l = [p1, p2, p3, p4]\n",
    "        res = set()\n",
    "        for i in range(0, 4):\n",
    "            for j in range(i+1, 4):\n",
    "                cur = (l[i][0] - l[j][0])**2 + (l[i][1] - l[j][1])**2\n",
    "                if cur == 0: return False\n",
    "                res.add(cur)\n",
    "        if len(res) != 2:   return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        dist = defaultdict(int)\n",
    "        p = [p1, p2, p3, p4]\n",
    "        for i in range(3):\n",
    "            for j in range(i+1, 4):\n",
    "                if p[i]==p[j]:\n",
    "                    return False\n",
    "                dist[(p[j][1]-p[i][1])**2 + (p[j][0]-p[i][0])**2] += 1\n",
    "        return len(dist)==2 and sorted(list(dist.values()))[0]==2 and (list(dist.keys())[0]==2*list(dist.keys())[1] or list(dist.keys())[1]==2*list(dist.keys())[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "\tdef validSquare(self, p1, p2, p3, p4):\n",
    "\t\ta = sorted([(p1[0], p1[1]), (p2[0], p2[1]), (p3[0], p3[1]), (p4[0], p4[1])])\n",
    "\t\tif len(set(a)) != 4: return False\n",
    "\t\tdef dist(p1, p2):\n",
    "\t\t\tx, y = p1[0] - p2[0], p1[1] - p2[1]\n",
    "\t\t\treturn x * x + y * y\n",
    "\t\treturn dist(a[0], a[1]) == dist(a[1], a[3]) and dist(a[1], a[3]) == dist(a[3], a[2]) and \\\n",
    "\t\t       dist(a[3], a[2]) == dist(a[2], a[0]) and dist(a[2], a[0]) == dist(a[0], a[1]) and \\\n",
    "\t\t       dist(a[0], a[3]) == dist(a[1], a[2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        def dist(a,b):\n",
    "            return pow(a[0]-b[0], 2) + pow(a[1]-b[1],2)\n",
    "        def rect(x,y,z):\n",
    "            if (x+y==z and x==y) or (x+z==y and x==z) or (y+z==x and y==z):\n",
    "                return True\n",
    "            return False\n",
    "        x_y = {}\n",
    "        for p in [p1,p2,p3,p4]:\n",
    "            if p[0] in x_y and p[1] == x_y[p[0]]:\n",
    "                return False\n",
    "            x_y[p[0]] = p[1]\n",
    "        x,y,z=dist(p1,p2),dist(p2,p3),dist(p1,p3)\n",
    "        if rect(x,y,z):\n",
    "            n = max(x,y,z)\n",
    "            if n == x:\n",
    "                b,c = dist(p1,p4),dist(p2,p4)\n",
    "            elif n==y:\n",
    "                b,c = dist(p2,p4),dist(p3,p4)\n",
    "            elif n==z:\n",
    "                b,c = dist(p1,p4),dist(p3,p4)\n",
    "            if b+c==n and b==min(x,y,z):\n",
    "                return True\n",
    "            else:\n",
    "                return False\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "def checkLength(v1: Tuple[int, int], v2: Tuple[int, int]) -> bool:\n",
    "    return v1[0] * v1[0] + v1[1] * v1[1] == v2[0] * v2[0] + v2[1] * v2[1]\n",
    "\n",
    "def checkMidPoint(p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "    return p1[0] + p2[0] == p3[0] + p4[0] and p1[1] + p2[1] == p3[1] + p4[1]\n",
    "\n",
    "def calCos(v1: Tuple[int, int], v2: Tuple[int, int]) -> int:\n",
    "    return v1[0] * v2[0] + v1[1] * v2[1]\n",
    "\n",
    "def help(p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "    v1 = (p1[0] - p2[0], p1[1] - p2[1])\n",
    "    v2 = (p3[0] - p4[0], p3[1] - p4[1])\n",
    "    return checkMidPoint(p1, p2, p3, p4) and checkLength(v1, v2) and calCos(v1, v2) == 0\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        if p1 == p2:\n",
    "            return False\n",
    "        if help(p1, p2, p3, p4):\n",
    "            return True\n",
    "        if p1 == p3:\n",
    "            return False\n",
    "        if help(p1, p3, p2, p4):\n",
    "            return True\n",
    "        if p1 == p4:\n",
    "            return False\n",
    "        if help(p1, p4, p2, p3):\n",
    "            return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        def getlen(p1, p2):\n",
    "            return  (p1[0] - p2[0]) ** 2 +  (p1[1] - p2[1]) ** 2\n",
    "\n",
    "        ans = []\n",
    "        ans.append(getlen(p1, p2))\n",
    "        ans.append(getlen(p1, p3))\n",
    "        ans.append(getlen(p1, p4))\n",
    "        ans.append(getlen(p2, p3))\n",
    "        ans.append(getlen(p2, p4))\n",
    "        ans.append(getlen(p3, p4))\n",
    "\n",
    "        ans = set(ans)\n",
    "        # print(ans)\n",
    "        if len(ans) == 2 and 0 not in ans:\n",
    "            return True\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "      stack = [[p1, p2], [p1, p3], [p1, p4], [p2, p3], [p2, p4], [p3, p4]]\n",
    "      line = collections.defaultdict(int)\n",
    "      for i in range(6):\n",
    "        x, y = stack[i]\n",
    "        line[(x[0] - y[0]) ** 2 + (x[1] - y[1]) ** 2] += 1\n",
    "      if len(line) != 2 or line[min(line.keys())] != 4:  return False\n",
    "      return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "      stack = [[p1, p2], [p1, p3], [p1, p4], [p2, p3], [p2, p4], [p3, p4]]\n",
    "      line = collections.defaultdict(int)\n",
    "      for i in range(6):\n",
    "        x, y = stack[i]\n",
    "        line[(x[0] - y[0]) ** 2 + (x[1] - y[1]) ** 2] += 1\n",
    "      if len(line) != 2 or line[min(line.keys())] != 4:  return False\n",
    "      return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        if p1 == p2 == p3 == p4:\n",
    "            return False\n",
    "        points = [p1,p2,p3,p4]\n",
    "        midX = p1[0] + p2[0] + p3[0] + p4[0]\n",
    "        midY = p1[1] + p2[1] + p3[1] + p4[1]\n",
    "        points = [(p[0] * 4 - midX, p[1] * 4 - midY) for p in points]\n",
    "        \n",
    "        rotated = {(-y, x) for x,y in points}\n",
    "        for p in points:\n",
    "            if tuple(p) not in rotated:\n",
    "                return False\n",
    "        return True        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        def innerP(v1, v2):\n",
    "            return v1[0] * v2[0] + v1[1] * v2[1]\n",
    "        \n",
    "        def norm2(v):\n",
    "            return v[0] * v[0] + v[1] * v[1]\n",
    "        \n",
    "        allVecs = [(p1[0] - p2[0], p1[1] - p2[1]), (p1[0] - p3[0], p1[1] - p3[1]), (p1[0] - p4[0], p1[1] - p4[1])]\n",
    "        if not len(set(allVecs)) == 3:\n",
    "            return False\n",
    "        prod_set = set()\n",
    "        norm_set = set()\n",
    "        for i in range(3):\n",
    "            for j in range(i + 1, 3):\n",
    "                prod_set.add(innerP(allVecs[i], allVecs[j]))\n",
    "            norm_set.add(norm2(allVecs[i]))\n",
    "        \n",
    "        if not len(prod_set) == 2 or not len(norm_set) == 2:\n",
    "            return False\n",
    "        \n",
    "        for prod in prod_set:\n",
    "            if prod and not prod in norm_set:\n",
    "                return False\n",
    "        \n",
    "        return True\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "def checkLength(v1: Tuple[int, int], v2: Tuple[int, int]) -> bool:\n",
    "    return v1[0] * v1[0] + v1[1] * v1[1] == v2[0] * v2[0] + v2[1] * v2[1]\n",
    "\n",
    "def checkMidPoint(p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "    return p1[0] + p2[0] == p3[0] + p4[0] and p1[1] + p2[1] == p3[1] + p4[1]\n",
    "\n",
    "def calCos(v1: Tuple[int, int], v2: Tuple[int, int]) -> int:\n",
    "    return v1[0] * v2[0] + v1[1] * v2[1]\n",
    "\n",
    "def help(p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "    v1 = (p1[0] - p2[0], p1[1] - p2[1])\n",
    "    v2 = (p3[0] - p4[0], p3[1] - p4[1])\n",
    "    return checkMidPoint(p1, p2, p3, p4) and checkLength(v1, v2) and calCos(v1, v2) == 0\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        if p1 == p2:\n",
    "            return False\n",
    "        if help(p1, p2, p3, p4):\n",
    "            return True\n",
    "        if p1 == p3:\n",
    "            return False\n",
    "        if help(p1, p3, p2, p4):\n",
    "            return True\n",
    "        if p1 == p4:\n",
    "            return False\n",
    "        if help(p1, p4, p2, p3):\n",
    "            return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        \"\"\"\n",
    "        先判断是否有点相等，再判断是否是菱形，然后判断是否为矩形\n",
    "        \"\"\"\n",
    "        def getDistance(p1, p2):\n",
    "            dx = p1[0] - p2[0]\n",
    "            dy = p1[1] - p2[1]\n",
    "            return dx*dx + dy*dy\n",
    "\n",
    "        def isRhombic(p1, p2, p3, p4):\n",
    "            \"\"\"\n",
    "            判断假设两两相连的点是否构成菱形\n",
    "            \"\"\"\n",
    "            return getDistance(p1, p2) == getDistance(p2, p3) == getDistance(p3, p4) == getDistance(p4, p1)\n",
    "        \n",
    "        def isRectangle(p1, p2, p3, p4):\n",
    "            return getDistance(p1, p3) == getDistance(p2, p4)\n",
    "\n",
    "        points = [p1, p2, p3, p4]\n",
    "        for i in range(3):\n",
    "            for j in range(i+1, 4):\n",
    "                if getDistance(points[i], points[j])  == 0:\n",
    "                    return False\n",
    "        \n",
    "        probs = [(p1, p3, p2, p4),\n",
    "                (p1, p2, p3, p4),\n",
    "                (p1, p2, p4, p3)]\n",
    "\n",
    "        for q1, q2, q3, q4 in probs:\n",
    "            if isRhombic(q1, q2, q3, q4) and isRectangle(q1, q2, q3, q4):\n",
    "                return True\n",
    "\n",
    "        return False\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        \"\"\"\n",
    "        4个点两两间的距离为6个 四个为变长 对角线2次\n",
    "        \"\"\"\n",
    "        combination = [p1,p2,p3,p4]\n",
    "        dist = []\n",
    "        for i in range(4):\n",
    "            for j in range(i+1,4):\n",
    "                dist.append((combination[i][0]-combination[j][0])**2+(combination[i][1]-combination[j][1])**2)\n",
    "        count = Counter(dist).most_common()\n",
    "        if len(count)==2 and count[0][1]==4 and count[1][1]==2 and count[0][0]*2==count[1][0]:\n",
    "            return True\n",
    "        return False\n",
    "       "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        def dist(p1: List[int], p2: List[int]):\n",
    "            d1 = abs(p1[0] - p2[0])\n",
    "            d2 = abs(p1[1] - p2[1])\n",
    "            return d1 * d1 + d2 * d2\n",
    "\n",
    "        s = set()\n",
    "        pp = (p1, p2, p3, p4)\n",
    "        for i in range(4):\n",
    "            for j in range(1, 4 - i):\n",
    "                s.add(dist(pp[i], pp[i + j]))\n",
    "        return len(s) == 2 and 0 not in s\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "      stack = [[p1, p2], [p1, p3], [p1, p4], [p2, p3], [p2, p4], [p3, p4]]\n",
    "      line = collections.defaultdict(int)\n",
    "      for i in range(6):\n",
    "        x, y = stack[i]\n",
    "        line[(x[0] - y[0]) ** 2 + (x[1] - y[1]) ** 2] += 1\n",
    "      if len(line) != 2 or line[min(line.keys())] != 4:  return False\n",
    "      return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "def checkLength(v1: Tuple[int, int], v2: Tuple[int, int]) -> bool:\n",
    "    return v1[0] * v1[0] + v1[1] * v1[1] == v2[0] * v2[0] + v2[1] * v2[1]\n",
    "\n",
    "def checkMidPoint(p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "    return p1[0] + p2[0] == p3[0] + p4[0] and p1[1] + p2[1] == p3[1] + p4[1]\n",
    "\n",
    "def calCos(v1: Tuple[int, int], v2: Tuple[int, int]) -> int:\n",
    "    return v1[0] * v2[0] + v1[1] * v2[1]\n",
    "\n",
    "def help(p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "    v1 = (p1[0] - p2[0], p1[1] - p2[1])\n",
    "    v2 = (p3[0] - p4[0], p3[1] - p4[1])\n",
    "    return checkMidPoint(p1, p2, p3, p4) and checkLength(v1, v2) and calCos(v1, v2) == 0\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        #如果两条对角线的中点相同：则说明以该两条对角线组成的四边形为「平行四边形」。\n",
    "        #在满足「条件一」的基础上，如果两条对角线的长度相同：则说明以该两条对角线组成的四边形为「矩形」。\n",
    "        #在满足「条件二」的基础上，如果两条对角线的相互垂直：则说明以该两条对角线组成的四边形为「正方形」。\n",
    "        if p1 == p2:\n",
    "            return False\n",
    "        if help(p1, p2, p3, p4):\n",
    "            return True\n",
    "        if p1 == p3:\n",
    "            return False\n",
    "        if help(p1, p3, p2, p4):\n",
    "            return True\n",
    "        if p1 == p4:\n",
    "            return False\n",
    "        if help(p1, p4, p2, p3):\n",
    "            return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        points = [p1, p2, p3, p4]\n",
    "        edges = []\n",
    "        for i in range(4):\n",
    "            for j in range(i+1, 4):\n",
    "                edges.append((points[i][0]-points[j][0])**2+(points[i][1]-points[j][1])**2)\n",
    "        edges.sort()\n",
    "\n",
    "        if edges[0]==edges[1]==edges[2]==edges[3] and edges[4]==edges[5] and edges[0]<edges[4]:\n",
    "            return True\n",
    "        return False\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        ps = sorted([p1, p2, p3, p4], key=lambda x: (x[0], x[1]))\n",
    "        ps[1], ps[0] = ps[0], ps[1]\n",
    "        side = ((ps[0][0] - ps[3][0]) ** 2 + (ps[0][1] - ps[3][1]) ** 2) ** 0.5\n",
    "        if side == 0:\n",
    "            return False\n",
    "        for i in range(3):\n",
    "            tmp_side = ((ps[i][0] - ps[i+1][0]) ** 2 + (ps[i][1] - ps[i+1][1]) ** 2) ** 0.5\n",
    "            if tmp_side != side:\n",
    "                return False\n",
    "        diagonal1 = ((ps[0][0] - ps[2][0]) ** 2 + (ps[0][1] - ps[2][1]) ** 2) ** 0.5\n",
    "        diagonal2 = ((ps[1][0] - ps[3][0]) ** 2 + (ps[1][1] - ps[3][1]) ** 2) ** 0.5\n",
    "        if diagonal1 != diagonal2:\n",
    "            return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "def checkLength(v1: Tuple[int, int], v2: Tuple[int, int]) -> bool:\n",
    "    return v1[0] * v1[0] + v1[1] * v1[1] == v2[0] * v2[0] + v2[1] * v2[1]\n",
    "\n",
    "def checkMidPoint(p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "    return p1[0] + p2[0] == p3[0] + p4[0] and p1[1] + p2[1] == p3[1] + p4[1]\n",
    "\n",
    "def calCos(v1: Tuple[int, int], v2: Tuple[int, int]) -> int:\n",
    "    return v1[0] * v2[0] + v1[1] * v2[1]\n",
    "\n",
    "def help(p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "    v1 = (p1[0] - p2[0], p1[1] - p2[1])\n",
    "    v2 = (p3[0] - p4[0], p3[1] - p4[1])\n",
    "    return checkMidPoint(p1, p2, p3, p4) and checkLength(v1, v2) and calCos(v1, v2) == 0\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        if p1 == p2:\n",
    "            return False\n",
    "        if help(p1, p2, p3, p4):\n",
    "            return True\n",
    "        if p1 == p3:\n",
    "            return False\n",
    "        if help(p1, p3, p2, p4):\n",
    "            return True\n",
    "        if p1 == p4:\n",
    "            return False\n",
    "        if help(p1, p4, p2, p3):\n",
    "            return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        all_dian = list((p1,p2,p3,p4))\n",
    "        for i in all_dian:\n",
    "            if all_dian.count(i) > 1:\n",
    "                return False\n",
    "        for dian in all_dian:\n",
    "            bian = []\n",
    "            for dian2 in all_dian:\n",
    "                bian.append( ((dian2[0]-dian[0]) ** 2 +(dian2[1]-dian[1]) ** 2) ** 0.5  )\n",
    "            bian.sort()\n",
    "            print(bian)\n",
    "            if bian[0] != 0 or bian[1] != bian[2] or (bian[1] ** 2 + bian[2] ** 2 - bian[3] ** 2) > 0.00000001:\n",
    "                return False\n",
    "        return True\n",
    "\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1, p2, p3, p4):\n",
    "\n",
    "        if p1[0] == p2[0] and p1[1] == p2[1]:\n",
    "            return False\n",
    "\n",
    "        length = list()\n",
    "        length.append(self.distance(p1, p2))\n",
    "        length.append(self.distance(p1, p3))\n",
    "        length.append(self.distance(p1, p4))\n",
    "        length.append(self.distance(p2, p3))\n",
    "        length.append(self.distance(p2, p4))\n",
    "        length.append(self.distance(p3, p4))\n",
    "\n",
    "        length.sort() \n",
    "\n",
    "        if length[0] == length[3] and length[4] == length[5] and length[0] * 2 == length[5]:\n",
    "            return True\n",
    "        else:\n",
    "            return False\n",
    "\n",
    "    def distance(self, start: List[int], end: List[int]) -> int:\n",
    "        return pow(start[0] - end[0], 2) + pow(start[1] - end[1], 2)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "\n",
    "        list1 = sorted([p1,p2,p3,p4],key=lambda x:(x[0],-x[1]))\n",
    "      \n",
    "        long1 = self.compute_long(list1[0],list1[1])\n",
    "        long2 = self.compute_long(list1[0],list1[2])\n",
    "        if long1!=long2:\n",
    "            return False\n",
    "        long3 = self.compute_long(list1[2],list1[3])\n",
    "        long4 = self.compute_long(list1[1],list1[3])\n",
    "        \n",
    "        if long3!=long4:\n",
    "            return False\n",
    "        if min(long1,long2,long3,long4)==0:\n",
    "            return False\n",
    "        if long2!=long3:\n",
    "            return False\n",
    "        \n",
    "        if self.iszhijiang(list1[1],list1[0],list1[2]):\n",
    "            return True\n",
    "\n",
    "        return False\n",
    "        \n",
    "    def iszhijiang(self,x,y,z):\n",
    "        temp1 = [x[0]-y[0],x[1]-y[1]]\n",
    "        temp2 = [z[0]-y[0],z[1]-y[1]]\n",
    "\n",
    "        dot = temp1[0] *temp2[0] + temp1[1] * temp2[1]\n",
    "        return dot==0\n",
    "\n",
    "    def compute_long(self,x,y):\n",
    "\n",
    "        return (x[0] -y[0])**2 + (x[1] -y[1])**2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "def checkLength(v1: Tuple[int, int], v2: Tuple[int, int]) -> bool:\n",
    "    return v1[0] * v1[0] + v1[1] * v1[1] == v2[0] * v2[0] + v2[1] * v2[1]\n",
    "\n",
    "def checkMidPoint(p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "    return p1[0] + p2[0] == p3[0] + p4[0] and p1[1] + p2[1] == p3[1] + p4[1]\n",
    "\n",
    "def calCos(v1: Tuple[int, int], v2: Tuple[int, int]) -> int:\n",
    "    return v1[0] * v2[0] + v1[1] * v2[1]\n",
    "\n",
    "def help(p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "    v1 = (p1[0] - p2[0], p1[1] - p2[1])\n",
    "    v2 = (p3[0] - p4[0], p3[1] - p4[1])\n",
    "    return checkMidPoint(p1, p2, p3, p4) and checkLength(v1, v2) and calCos(v1, v2) == 0\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        if p1 == p2:\n",
    "            return False\n",
    "        if help(p1, p2, p3, p4):\n",
    "            return True\n",
    "        if p1 == p3:\n",
    "            return False\n",
    "        if help(p1, p3, p2, p4):\n",
    "            return True\n",
    "        if p1 == p4:\n",
    "            return False\n",
    "        if help(p1, p4, p2, p3):\n",
    "            return True\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def A(self,p1: List[int], p2: List[int]):\n",
    "        return (p2[0]-p1[0])*(p2[0]-p1[0]) + (p2[1]-p1[1])*(p2[1]-p1[1])\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        a = {}\n",
    "        c = []\n",
    "        b = self.A(p1,p2)\n",
    "        if b in a:\n",
    "            a[b] += 1\n",
    "        else:\n",
    "            a[b] = 1\n",
    "            c.append(b)\n",
    "        b = self.A(p1,p3)\n",
    "        if b in a:\n",
    "            a[b] += 1\n",
    "        else:\n",
    "            a[b] = 1\n",
    "            c.append(b)\n",
    "        b = self.A(p1,p4)\n",
    "        if b in a:\n",
    "            a[b] += 1\n",
    "        else:\n",
    "            a[b] = 1\n",
    "            c.append(b)\n",
    "        b = self.A(p2,p3)\n",
    "        if b in a:\n",
    "            a[b] += 1\n",
    "        else:\n",
    "            a[b] = 1\n",
    "            c.append(b)\n",
    "        b = self.A(p2,p4)\n",
    "        if b in a:\n",
    "            a[b] += 1\n",
    "        else:\n",
    "            a[b] = 1\n",
    "            c.append(b)\n",
    "        b = self.A(p3,p4)\n",
    "        if b in a:\n",
    "            a[b] += 1\n",
    "        else:\n",
    "            a[b] = 1\n",
    "            c.append(b)\n",
    "        if len(c) != 2:\n",
    "            return False\n",
    "        c.sort()\n",
    "        if c[0] == 0 or c[0] * 2 != c[1] or a[c[1]] != 2:\n",
    "            return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        pointlist=[p1,p2,p3,p4]\n",
    "        pointlist=sorted(pointlist,key= lambda x:(x[0],x[1]))\n",
    "        p1=pointlist[0]\n",
    "        p2=pointlist[1]\n",
    "        p3=pointlist[2]\n",
    "        p4=pointlist[3]\n",
    "        angle = ((p1[0]-p2[0])*(p1[0]-p3[0])+(p1[1]-p2[1])*(p1[1]-p3[1]))==0 and (p1[0]-p2[0]!=p1[0]-p3[0] or p1[1]-p2[1]!=p1[1]-p3[1])\n",
    "        def callength(p,q):\n",
    "            return (p[1]-q[1])**2+(p[0]-q[0])**2\n",
    "        len1=callength(p1,p2)\n",
    "        len2=callength(p1,p3)\n",
    "        len3=callength(p4,p2)\n",
    "        len4=callength(p4,p3)\n",
    "        return len1==len2 and angle and len3==len4 and len3==len2 and len1==len4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import math\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        p12 = int(abs(p1[0] - p2[0])) ** 2 + int(abs(p1[1] - p2[1])) ** 2\n",
    "        p13 = int(abs(p1[0] - p3[0])) ** 2 + int(abs(p1[1] - p3[1])) ** 2\n",
    "        p14 = int(abs(p1[0] - p4[0])) ** 2 + int(abs(p1[1] - p4[1])) ** 2\n",
    "\n",
    "        lengthList = [p12, p13, p14]\n",
    "        lengthList.sort()\n",
    "\n",
    "        if lengthList[0] == 0 :\n",
    "            return False\n",
    "\n",
    "        if lengthList[0] != lengthList[1] :\n",
    "            return False \n",
    "\n",
    "        if lengthList[0] * 2 != lengthList[2] :\n",
    "            return False\n",
    "\n",
    "          \n",
    "        p21 = int(abs(p2[0] - p1[0])) ** 2 + int(abs(p2[1] - p1[1])) ** 2\n",
    "        p23 = int(abs(p2[0] - p3[0])) ** 2 + int(abs(p2[1] - p3[1])) ** 2\n",
    "        p24 = int(abs(p2[0] - p4[0])) ** 2 + int(abs(p2[1] - p4[1])) ** 2\n",
    "\n",
    "        lengthList2 = [p21, p23, p24]\n",
    "        lengthList2.sort()\n",
    "\n",
    "        if lengthList2[0] == 0 :\n",
    "            return False\n",
    "\n",
    "        if lengthList2[0] != lengthList2[1] :\n",
    "            return False \n",
    "\n",
    "        if lengthList2[0] * 2 != lengthList2[2] :\n",
    "            return False\n",
    "\n",
    "        p31 = int(abs(p3[0] - p1[0])) ** 2 + int(abs(p3[1] - p1[1])) ** 2\n",
    "        p32 = int(abs(p3[0] - p2[0])) ** 2 + int(abs(p3[1] - p2[1])) ** 2\n",
    "        p34 = int(abs(p3[0] - p4[0])) ** 2 + int(abs(p3[1] - p4[1])) ** 2\n",
    "\n",
    "        lengthList3 = [p31, p32, p34]\n",
    "        lengthList3.sort()\n",
    "\n",
    "        if lengthList3[0] == 0 :\n",
    "            return False\n",
    "\n",
    "        if lengthList3[0] != lengthList3[1] :\n",
    "            return False \n",
    "\n",
    "        if lengthList3[0] * 2 != lengthList3[2] :\n",
    "            return False\n",
    "\n",
    "\n",
    "        if lengthList[0] != lengthList2[0] or lengthList[0] != lengthList3[0]:\n",
    "            return False\n",
    "\n",
    "        if lengthList[2] != lengthList2[2] or lengthList[2] != lengthList3[2]:\n",
    "            return False\n",
    "\n",
    "        return True\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        def dist(p1, p2):\n",
    "            x1, y1 = p1\n",
    "            x2, y2 = p2\n",
    "            return (x1 - x2)**2 + (y1 - y2)**2\n",
    "        d = [dist(p1, p2), dist(p1, p3), dist(p1, p4), dist(p2, p3), dist(p2, p4), dist(p3, p4)]\n",
    "        cnt = Counter(d)\n",
    "        dst = sorted(cnt)\n",
    "        return True if cnt[dst[0]] == 4 and cnt[dst[1]] == 2 and dst[0]*2 == dst[1] else False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        if(p1 == p2 or p2 == p3 or p3== p4 or p1 == p3 or p2 == p4 or p1 == p4):\n",
    "            return False\n",
    "        elif([abs(p1[0]-p3[0]),abs(p1[1]-p3[1])] == [abs(p1[1]-p4[1]),abs(p1[0]-p4[0])] ==\n",
    "        [abs(p2[1]-p3[1]),abs(p2[0]-p3[0])] == [abs(p2[0]-p4[0]),abs(p2[1]-p4[1])] and \n",
    "        [abs(p1[0]-p2[0]),abs(p1[1]-p2[1])] == [abs(p3[1]-p4[1]),abs(p3[0]-p4[0])]):\n",
    "            return True\n",
    "        elif([abs(p1[0]-p2[0]),abs(p1[1]-p2[1])] == [abs(p1[1]-p4[1]),abs(p1[0]-p4[0])] == \n",
    "        [abs(p2[1]-p3[1]),abs(p2[0]-p3[0])] == [abs(p3[0]-p4[0]),abs(p3[1]-p4[1])] and \n",
    "        [abs(p1[0]-p3[0]),abs(p1[1]-p3[1])] == [abs(p2[1]-p4[1]),abs(p2[0]-p4[0])]):\n",
    "            return True\n",
    "        elif([abs(p1[0]-p3[0]),abs(p1[1]-p3[1])] == [abs(p1[1]-p2[1]),abs(p1[0]-p2[0])] == \n",
    "        [abs(p4[1]-p3[1]),abs(p4[0]-p3[0])] == [abs(p2[0]-p4[0]),abs(p2[1]-p4[1])] and \n",
    "        [abs(p1[0]-p4[0]),abs(p1[1]-p4[1])] == [abs(p3[1]-p2[1]),abs(p3[0]-p2[0])]):\n",
    "            return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "def checkLength(v1: Tuple[int, int], v2: Tuple[int, int]) -> bool:\n",
    "    return v1[0] * v1[0] + v1[1] * v1[1] == v2[0] * v2[0] + v2[1] * v2[1]\n",
    "\n",
    "def checkMidPoint(p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "    return p1[0] + p2[0] == p3[0] + p4[0] and p1[1] + p2[1] == p3[1] + p4[1]\n",
    "\n",
    "def calCos(v1: Tuple[int, int], v2: Tuple[int, int]) -> int:\n",
    "    return v1[0] * v2[0] + v1[1] * v2[1]\n",
    "\n",
    "def help(p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "    v1 = (p1[0] - p2[0], p1[1] - p2[1])\n",
    "    v2 = (p3[0] - p4[0], p3[1] - p4[1])\n",
    "    return checkMidPoint(p1, p2, p3, p4) and checkLength(v1, v2) and calCos(v1, v2) == 0\n",
    "\n",
    "class Solution:\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        if p1 == p2:\n",
    "            return False\n",
    "        if help(p1, p2, p3, p4):\n",
    "            return True\n",
    "        if p1 == p3:\n",
    "            return False\n",
    "        if help(p1, p3, p2, p4):\n",
    "            return True\n",
    "        if p1 == p4:\n",
    "            return False\n",
    "        if help(p1, p4, p2, p3):\n",
    "            return True\n",
    "        return False\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "\n",
    "\n",
    "    def inner_p_zero(self, dot_s, dot_t1, dot_t2):\n",
    "\n",
    "        # vec1: (x1,y1)\n",
    "\n",
    "        vec1 = (dot_t1[0]-dot_s[0], dot_t1[1]-dot_s[1])\n",
    "        vec2 = (dot_t2[0]-dot_s[0], dot_t2[1]-dot_s[1])\n",
    "\n",
    "        inner_product = vec1[0]*vec2[0] + vec1[1]*vec2[1]\n",
    "\n",
    "        return not inner_product\n",
    "\n",
    "    def equal_len(self, dot_s, dot_t1, dot_t2):\n",
    "        len1 = (dot_t1[0]-dot_s[0])**2 + (dot_t1[1]-dot_s[1])**2\n",
    "        len2 = (dot_t2[0]-dot_s[0])**2 + (dot_t2[1]-dot_s[1])**2\n",
    "\n",
    "        return len1 == len2\n",
    "\n",
    "    # def is_square(dot1, dot2, dot3, dot4):\n",
    "    #     if (inner_p_zero(dot1, dot2, dot3) and inner_p_zero(dot4, dot2, dot3) and equal_len(dot1, dot2, dot3)):\n",
    "    #         # print(\"1\")\n",
    "    #         return True\n",
    "    #     elif (inner_p_zero(dot1, dot2, dot4) and inner_p_zero(dot3, dot2, dot4) and equal_len(dot1, dot2, dot4)):\n",
    "    #         # print(\"2\")\n",
    "    #         return True\n",
    "    #     elif (inner_p_zero(dot1, dot3, dot4) and inner_p_zero(dot2, dot3, dot4) and equal_len(dot1, dot3, dot4)):\n",
    "    #         # print(\"3\")\n",
    "    #         return True\n",
    "\n",
    "    #     return False\n",
    "    def validSquare(self, p1: List[int], p2: List[int], p3: List[int], p4: List[int]) -> bool:\n",
    "        dot1, dot2, dot3, dot4 = tuple(p1), tuple(p2), tuple(p3), tuple(p4)\n",
    "        t = (dot1, dot2, dot3, dot4)\n",
    "        # print(type(t))\n",
    "        set_ = set(t)\n",
    "        print(set_)\n",
    "        print(type(set_))\n",
    "        if len(set_) != 4:\n",
    "            return False \n",
    "        if (self.inner_p_zero(dot1, dot2, dot3) and self.inner_p_zero(dot4, dot2, dot3) and self.equal_len(dot1, dot2, dot3)):\n",
    "            # print(\"1\")\n",
    "            return True\n",
    "        elif (self.inner_p_zero(dot1, dot2, dot4) and self.inner_p_zero(dot3, dot2, dot4) and self.equal_len(dot1, dot2, dot4)):\n",
    "            # print(\"2\")\n",
    "            return True\n",
    "        elif (self.inner_p_zero(dot1, dot3, dot4) and self.inner_p_zero(dot2, dot3, dot4) and self.equal_len(dot1, dot3, dot4)):\n",
    "            # print(\"3\")\n",
    "            return True\n",
    "\n",
    "        return False"
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 2
}
